package com.algorithms.arrays;

import com.algorithms.utils.AlgorithmException;

/**
 * No-Count Queue is designed without usage of <b>length</b> variable<br>
 * it has actual size = max size(Queue) + 1
 * 
 * @author minhld
 *
 * @param <T>
 */
public class NoCountQueue<T> extends AbstractArray<T> {
	private int rear = INVALID_INDEX;
	private int front = 0;

	public NoCountQueue(int maxElementCount) {
		super(maxElementCount + 1);
	}
	
	@Override
	public T pop() throws AlgorithmException {
		if (isEmpty()){
			throw new AlgorithmException("queue is empty.");
		}else{
			return this.data[front++];
		}
	}

	@Override
	public void push(T value) throws AlgorithmException {
		if (isFull()){
			throw new AlgorithmException("queue is full.");
		}else{
			if (rear == this.maxElementCount - 1){
				rear = INVALID_INDEX;
			}
			this.data[++rear] = value;
		}
	}

	@Override
	public T peak() {
		return this.data[front];
	}

	@Override
	public boolean isEmpty() {
		return this.rear == this.front - 1 ||
				this.rear == this.front + (this.maxElementCount - 1);
	}
	
	@Override
	public boolean isFull() {
		return this.rear == this.front - 2 || 
				this.rear == this.front + (this.maxElementCount - 2);
	}
	
}
